/**
 * 统一的API请求封装
 * 封装this.$request.get/post方法
 */

import storage from './storage';

// 基础配置
const baseConfig = {
  baseURL: 'http://localhost:3000', // backend服务地址
  timeout: 10000, // 请求超时时间
  headers: {
    'Content-Type': 'application/json'
  }
}

// 请求拦截器处理函数
const requestInterceptor = (config) => {
  // 获取token并添加到请求头
  const token = storage.get('token');
  if (token) {
    config.headers = {
      ...config.headers,
      'Authorization': `Bearer ${token}`
    };
  }
  
  // 添加时间戳避免缓存
  if (config.method?.toLowerCase() === 'get' && config.params) {
    config.params._t = Date.now();
  }
  
  return config;
}

// 响应拦截器处理函数
const responseInterceptor = (response) => {
  const res = response.data;
  
  // 处理token过期的情况
  if (res.code === 401) {
    // token过期或无效，清除本地存储的token并跳转到登录页
    storage.remove('token');
    storage.remove('userInfo');
    
    // 显示登录提示
    uni.showToast({
      title: '登录已过期，请重新登录',
      icon: 'none',
      duration: 2000
    });
    
    // 延时跳转到登录页
    setTimeout(() => {
      uni.navigateTo({
        url: '/pages/my/login'
      });
    }, 1500);
    
    return Promise.reject(new Error('登录已过期'));
  }
  
  // 处理其他错误情况
  if (res.code !== 200 && res.code !== undefined) {
    // 显示错误提示
    uni.showToast({
      title: res.message || '请求失败',
      icon: 'none',
      duration: 2000
    });
    
    console.error('API请求失败:', res.message || '未知错误');
    return Promise.reject(res);
  }
  
  // 成功情况直接返回数据
  return res;
}

// 错误处理函数
const errorHandler = (error) => {
  console.error('API请求错误详情:', error);
  
  let errorMsg = '请求失败，请稍后重试';
  
  // 根据错误类型提供更友好的错误信息
  if (error.errMsg) {
    if (error.errMsg.includes('timeout')) {
      errorMsg = '请求超时，请检查网络连接';
    } else if (error.errMsg.includes('network')) {
      errorMsg = '网络连接失败，请检查网络设置';
    } else if (error.errMsg.includes('abort')) {
      errorMsg = '请求被取消';
    }
  }
  
  // 显示错误提示
  uni.showToast({
    title: errorMsg,
    icon: 'none',
    duration: 2000
  });
  
  return Promise.reject(error);
}

// 封装request方法
const request = (config) => {
  return new Promise((resolve, reject) => {
    // 应用请求拦截器
    const requestConfig = requestInterceptor({
      ...baseConfig,
      ...config
    })
    
    // 转换get参数
    if (requestConfig.method?.toLowerCase() === 'get' && requestConfig.params) {
      // 将params转换为查询字符串
      const queryString = Object.keys(requestConfig.params)
        .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(requestConfig.params[key])}`)
        .join('&')
      
      requestConfig.url = requestConfig.url + (requestConfig.url.includes('?') ? '&' : '?') + queryString
      delete requestConfig.params
    }
    
    // 使用uni.request发起请求
    uni.request({
      url: requestConfig.baseURL + requestConfig.url,
      method: requestConfig.method || 'GET',
      header: requestConfig.headers,
      data: requestConfig.data,
      timeout: requestConfig.timeout,
      success: (res) => {
        try {
          // 应用响应拦截器
          const result = responseInterceptor({
            data: res.data,
            status: res.statusCode,
            statusText: res.errMsg,
            headers: res.header,
            config: requestConfig
          })
          resolve(result)
        } catch (error) {
          reject(error)
        }
      },
      fail: (err) => {
        reject(errorHandler(err))
      }
    })
  })
}

// 封装uploadFile方法
const upload = (url, fileOptions) => {
  return new Promise((resolve, reject) => {
    // 应用请求拦截器
    const requestConfig = requestInterceptor({
      ...baseConfig,
      url,
      ...fileOptions
    })
    
    // 移除Content-Type，让uni.uploadFile自动处理
    const uploadHeaders = {...requestConfig.headers}
    if (uploadHeaders['Content-Type']) {
      delete uploadHeaders['Content-Type']
    }
    
    // 构建查询参数
    let uploadUrl = requestConfig.baseURL + requestConfig.url
    if (requestConfig.params) {
      const queryString = Object.keys(requestConfig.params)
        .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(requestConfig.params[key])}`)
        .join('&')
      uploadUrl = uploadUrl + (uploadUrl.includes('?') ? '&' : '?') + queryString
    }
    console.log(requestConfig)
    // 使用uni.uploadFile发起文件上传
    uni.uploadFile({
      url: uploadUrl,
      filePath: requestConfig.file,
      name: requestConfig.name || 'file',
      header: uploadHeaders,
      formData: requestConfig.formData || {},
      timeout: requestConfig.timeout,
      success: (res) => {
        try {
          // 解析响应数据
          let responseData = res.data
          if (typeof responseData === 'string') {
            try {
              responseData = JSON.parse(responseData)
            } catch (e) {
              // 如果解析失败，保持原字符串
            }
          }
          
          // 应用响应拦截器
          const result = responseInterceptor({
            data: responseData,
            status: res.statusCode,
            statusText: res.errMsg,
            headers: res.header,
            config: requestConfig
          })
          resolve(result)
        } catch (error) {
          reject(error)
        }
      },
      fail: (err) => {
        reject(errorHandler(err))
      },
      // 可选的进度回调
      ...(requestConfig.onProgressUpdate && { onProgressUpdate: requestConfig.onProgressUpdate })
    })
  })
}

// 封装get请求
export const get = (url, params = {}) => {
  return request({
    url,
    method: 'get',
    params
  })
}

// 封装post请求
export const post = (url, data = {}) => {
  return request({
    url,
    method: 'post',
    data
  })
}

// 封装上传方法
export const uploadFile = (url, fileOptions = {}) => {
  return upload(url, fileOptions)
}

// 导出默认request方法
export default {
  get,
  post,
  uploadFile
}